﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Xml.Serialization;
using System.Windows;

namespace USM_Presenter.ViewModels
{
    [Serializable()]
    public class PageViewModel : INotifyPropertyChanged
    {
        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(info));
        }

        #endregion

        private PageViewModel _parentPage;
        [XmlIgnore]
        public PageViewModel ParentPage
        {
            get { return _parentPage; }
            set { _parentPage = value; }
        }

        private PresentationViewModel _parent;
        [XmlIgnore]
        public PresentationViewModel Parent
        {
            get { return _parent; }
            set { _parent = value; }
        }

        public PageViewModel()
        {
            this._pages.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(_pages_CollectionChanged);
        }

        public PageViewModel(PresentationViewModel parent)
            : this()
        {
            _parent = parent;
        }

        public PageViewModel(PresentationViewModel parent, UseAsEnum useas)
            : this(parent)
        {
            UseAs = useas;
        }

        private Guid _primaryID = Guid.NewGuid();
        public Guid PrimaryID
        {
            get { return _primaryID; }
            set { _primaryID = value; }
        }

        private string _pageBackgroundImage;
        public string PageBackgroundImage
        {
            get { return _pageBackgroundImage; }
            set
            {
                if (_pageBackgroundImage != value)
                {
                    _pageBackgroundImage = value;
                    NotifyPropertyChanged("PageBackgroundImage");
                }
            }
        }


        private string _buttonImage = "images/ButtonNone.png";
        public string ButtonImage
        {
            get { return _buttonImage; }
            set
            {
                if (value != _buttonImage)
                {
                    _buttonImage = value;
                    NotifyPropertyChanged("ButtonImage");
                }
            }
        }

        private string _buttonText = "Button";
        public string ButtonText
        {
            get { return _buttonText; }
            set
            {
                if (value != _buttonText)
                {
                    _buttonText = value;
                    NotifyPropertyChanged("ButtonText");
                }
            }
        }

        private double _buttonWidth = 250;
        public double ButtonWidth
        {
            get { return _buttonWidth; }
            set
            {
                if (value != _buttonWidth)
                {
                    _buttonWidth = value;
                    NotifyPropertyChanged("ButtonWidth");
                }
            }
        }

        private double _buttonHeight = 250;
        public double ButtonHeight
        {
            get { return _buttonHeight; }
            set
            {
                if (value != _buttonHeight)
                {
                    _buttonHeight = value;
                    NotifyPropertyChanged("ButtonHeight");
                }
            }
        }

        [XmlIgnore]
        public object ButtonStyle
        {
            get
            {
                if (UseSimpleButtonStyle)
                    return Application.Current.Resources["SimplePageButton"];
                else
                    return Application.Current.Resources["PageButton"];
            }
        }

        private bool _useSimpleButtonStyle = false;
        public bool UseSimpleButtonStyle
        {
            get { return _useSimpleButtonStyle; }
            set
            {
                if (value != _useSimpleButtonStyle)
                {
                    _useSimpleButtonStyle = value;
                    NotifyPropertyChanged("UseSimpleButtonStyle");
                    NotifyPropertyChanged("ButtonStyle");
                }
            }
        }

        #region Content Alignment

        private HorizontalAlignment _horizontalContentAlignment = HorizontalAlignment.Center;
        public HorizontalAlignment HorizontalContentAlignment
        {
            get { return _horizontalContentAlignment; }
            set
            {
                if (value != _horizontalContentAlignment)
                {
                    _horizontalContentAlignment = value;
                    NotifyPropertyChanged("HorizontalContentAlignment");
                }
            }
        }

        private VerticalAlignment _verticalContentAlignment = VerticalAlignment.Center;
        public VerticalAlignment VerticalContentAlignment
        {
            get { return _verticalContentAlignment; }
            set
            {
                if (value != _verticalContentAlignment)
                {
                    _verticalContentAlignment = value;
                    NotifyPropertyChanged("VerticalContentAlignment");
                }
            }
        }

        [XmlIgnore]
        public bool AlignContentLeftUp
        {
            get { return _horizontalContentAlignment == HorizontalAlignment.Left && _verticalContentAlignment == VerticalAlignment.Top; }
            set
            {
                HorizontalContentAlignment = HorizontalAlignment.Left;
                VerticalContentAlignment = VerticalAlignment.Top;

                NotifyPropertyChanged("AlignContentLeftUp");
                NotifyPropertyChanged("AlignContentMidUp");
                NotifyPropertyChanged("AlignContentRightUp");

                NotifyPropertyChanged("AlignContentLeftMid");
                NotifyPropertyChanged("AlignContentMidMid");
                NotifyPropertyChanged("AlignContentRightMid");

                NotifyPropertyChanged("AlignContentLeftDown");
                NotifyPropertyChanged("AlignContentMidDown");
                NotifyPropertyChanged("AlignContentRightDown");
            }
        }

        [XmlIgnore]
        public bool AlignContentMidUp
        {
            get { return _horizontalContentAlignment == HorizontalAlignment.Center && _verticalContentAlignment == VerticalAlignment.Top; }
            set
            {
                HorizontalContentAlignment = HorizontalAlignment.Center;
                VerticalContentAlignment = VerticalAlignment.Top;

                NotifyPropertyChanged("AlignContentLeftUp");
                NotifyPropertyChanged("AlignContentMidUp");
                NotifyPropertyChanged("AlignContentRightUp");

                NotifyPropertyChanged("AlignContentLeftMid");
                NotifyPropertyChanged("AlignContentMidMid");
                NotifyPropertyChanged("AlignContentRightMid");

                NotifyPropertyChanged("AlignContentLeftDown");
                NotifyPropertyChanged("AlignContentMidDown");
                NotifyPropertyChanged("AlignContentRightDown");
            }
        }

        [XmlIgnore]
        public bool AlignContentRightUp
        {
            get { return _horizontalContentAlignment == HorizontalAlignment.Right && _verticalContentAlignment == VerticalAlignment.Top; }
            set
            {
                HorizontalContentAlignment = HorizontalAlignment.Right;
                VerticalContentAlignment = VerticalAlignment.Top;

                NotifyPropertyChanged("AlignContentLeftUp");
                NotifyPropertyChanged("AlignContentMidUp");
                NotifyPropertyChanged("AlignContentRightUp");

                NotifyPropertyChanged("AlignContentLeftMid");
                NotifyPropertyChanged("AlignContentMidMid");
                NotifyPropertyChanged("AlignContentRightMid");

                NotifyPropertyChanged("AlignContentLeftDown");
                NotifyPropertyChanged("AlignContentMidDown");
                NotifyPropertyChanged("AlignContentRightDown");
            }
        }


        [XmlIgnore]
        public bool AlignContentLeftMid
        {
            get { return _horizontalContentAlignment == HorizontalAlignment.Left && _verticalContentAlignment == VerticalAlignment.Center; }
            set
            {
                HorizontalContentAlignment = HorizontalAlignment.Left;
                VerticalContentAlignment = VerticalAlignment.Center;

                NotifyPropertyChanged("AlignContentLeftUp");
                NotifyPropertyChanged("AlignContentMidUp");
                NotifyPropertyChanged("AlignContentRightUp");

                NotifyPropertyChanged("AlignContentLeftMid");
                NotifyPropertyChanged("AlignContentMidMid");
                NotifyPropertyChanged("AlignContentRightMid");

                NotifyPropertyChanged("AlignContentLeftDown");
                NotifyPropertyChanged("AlignContentMidDown");
                NotifyPropertyChanged("AlignContentRightDown");
            }
        }

        [XmlIgnore]
        public bool AlignContentMidMid
        {
            get { return _horizontalContentAlignment == HorizontalAlignment.Center && _verticalContentAlignment == VerticalAlignment.Center; }
            set
            {
                HorizontalContentAlignment = HorizontalAlignment.Center;
                VerticalContentAlignment = VerticalAlignment.Center;

                NotifyPropertyChanged("AlignContentLeftUp");
                NotifyPropertyChanged("AlignContentMidUp");
                NotifyPropertyChanged("AlignContentRightUp");

                NotifyPropertyChanged("AlignContentLeftMid");
                NotifyPropertyChanged("AlignContentMidMid");
                NotifyPropertyChanged("AlignContentRightMid");

                NotifyPropertyChanged("AlignContentLeftDown");
                NotifyPropertyChanged("AlignContentMidDown");
                NotifyPropertyChanged("AlignContentRightDown");
            }
        }

        [XmlIgnore]
        public bool AlignContentRightMid
        {
            get { return _horizontalContentAlignment == HorizontalAlignment.Right && _verticalContentAlignment == VerticalAlignment.Center; }
            set
            {
                HorizontalContentAlignment = HorizontalAlignment.Right;
                VerticalContentAlignment = VerticalAlignment.Center;

                NotifyPropertyChanged("AlignContentLeftUp");
                NotifyPropertyChanged("AlignContentMidUp");
                NotifyPropertyChanged("AlignContentRightUp");

                NotifyPropertyChanged("AlignContentLeftMid");
                NotifyPropertyChanged("AlignContentMidMid");
                NotifyPropertyChanged("AlignContentRightMid");

                NotifyPropertyChanged("AlignContentLeftDown");
                NotifyPropertyChanged("AlignContentMidDown");
                NotifyPropertyChanged("AlignContentRightDown");
            }
        }

        [XmlIgnore]
        public bool AlignContentLeftDown
        {
            get { return _horizontalContentAlignment == HorizontalAlignment.Left && _verticalContentAlignment == VerticalAlignment.Bottom; }
            set
            {
                HorizontalContentAlignment = HorizontalAlignment.Left;
                VerticalContentAlignment = VerticalAlignment.Bottom;

                NotifyPropertyChanged("AlignContentLeftUp");
                NotifyPropertyChanged("AlignContentMidUp");
                NotifyPropertyChanged("AlignContentRightUp");

                NotifyPropertyChanged("AlignContentLeftMid");
                NotifyPropertyChanged("AlignContentMidMid");
                NotifyPropertyChanged("AlignContentRightMid");

                NotifyPropertyChanged("AlignContentLeftDown");
                NotifyPropertyChanged("AlignContentMidDown");
                NotifyPropertyChanged("AlignContentRightDown");
            }
        }

        [XmlIgnore]
        public bool AlignContentMidDown
        {
            get { return _horizontalContentAlignment == HorizontalAlignment.Center && _verticalContentAlignment == VerticalAlignment.Bottom; }
            set
            {
                HorizontalContentAlignment = HorizontalAlignment.Center;
                VerticalContentAlignment = VerticalAlignment.Bottom;

                NotifyPropertyChanged("AlignContentLeftUp");
                NotifyPropertyChanged("AlignContentMidUp");
                NotifyPropertyChanged("AlignContentRightUp");

                NotifyPropertyChanged("AlignContentLeftMid");
                NotifyPropertyChanged("AlignContentMidMid");
                NotifyPropertyChanged("AlignContentRightMid");

                NotifyPropertyChanged("AlignContentLeftDown");
                NotifyPropertyChanged("AlignContentMidDown");
                NotifyPropertyChanged("AlignContentRightDown");
            }
        }

        [XmlIgnore]
        public bool AlignContentRightDown
        {
            get { return _horizontalContentAlignment == HorizontalAlignment.Right && _verticalContentAlignment == VerticalAlignment.Bottom; }
            set
            {
                HorizontalContentAlignment = HorizontalAlignment.Right;
                VerticalContentAlignment = VerticalAlignment.Bottom;

                NotifyPropertyChanged("AlignContentLeftUp");
                NotifyPropertyChanged("AlignContentMidUp");
                NotifyPropertyChanged("AlignContentRightUp");

                NotifyPropertyChanged("AlignContentLeftMid");
                NotifyPropertyChanged("AlignContentMidMid");
                NotifyPropertyChanged("AlignContentRightMid");

                NotifyPropertyChanged("AlignContentLeftDown");
                NotifyPropertyChanged("AlignContentMidDown");
                NotifyPropertyChanged("AlignContentRightDown");
            }
        }

        #endregion

        #region Elements
        public enum UseAsEnum { Thumb, Page }
        public UseAsEnum UseAs { get; set; }

        private ObservableCollection<PageViewModel> _pages = new ObservableCollection<PageViewModel>();
        public ObservableCollection<PageViewModel> Pages
        {
            get { return _pages; }
            set
            {
                if (value != _pages)
                {
                    _pages = value;
                    NotifyPropertyChanged("Pages");
                }
            }
        }

        private void _pages_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
                foreach (PageViewModel p in _pages)
                    p.ParentPage = this;
        }

        private ObservableCollection<ThumbElementBase> _elements = new ObservableCollection<ThumbElementBase>();
        public ObservableCollection<ThumbElementBase> Elements
        {
            get { return _elements; }
            set
            {
                if (value != _elements)
                {
                    _elements = value;
                    NotifyPropertyChanged("Images");
                }
            }
        }

        internal ThumbElementBase FindElement(Guid g)
        {
            for (int i = 0; i < Elements.Count; i++)
                if (Elements[i].PrimaryID == g)
                    return Elements[i] as ThumbElementBase;

            return null;
        }

        internal void AddVideo(string path, string videoPath)
        {
            Elements.Add(new VideoViewModel(videoPath, path, this));
        }

        internal void AddImage(string path)
        {
            Elements.Add(new ImageViewModel(path, this));
        }

        internal void DeleteAllElements()
        {
            Elements.Clear();
        }

        internal void DeleteElement(Guid g)
        {
            ThumbElementBase element = FindElement(g);
            if (element != null) Elements.Remove(element);
        }
        #endregion

    }
}
